using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using gudusoft.gsqlparser;
using gudusoft.gsqlparser.Units;

namespace syntaxhighlighting
{
    class syntaxhighlighting
    {

        static void Main(string[] args)
        {
            string usage = "Demo of General SQL Parser at http://www.sqlparser.com" + Environment.NewLine
            + "Usage:" + Environment.NewLine
             + "syntaxhighlighting -i insql.txt  -d mssql -t html -o outsql.html" + Environment.NewLine
             + "-i insql.txt, \t input sql file, must be specified" + Environment.NewLine
            + "-d mssql, \t sql engine used to handle the input sql, can be one of: access, db2,mssql,mysql,oracle, if ommitted, mssql engine will be used as default" + Environment.NewLine
            + "-t html, \t output type of the inputsql, can be formatted html, rtf,html2(use font instead of div)" + Environment.NewLine
            + "-o outsql.txt, \t save the output to this file,if ommitted, will write to stand output";


            if (args.Length == 0)
            {
                Console.WriteLine(usage);
                return;
            }

            string inputfile = "";
            string dbvendor = "";
            string outtype = "";
            string outfile = "";

            for (int t = 0; t < args.Length; t++)
            {
                if (args[t] == "-i")
                {
                    if (t + 1 < args.Length)
                    {
                        inputfile = args[t + 1];
                    }
                }

                if (args[t] == "-d")
                {
                    if (t + 1 < args.Length)
                    {
                        dbvendor = args[t + 1];
                    }
                }

                if (args[t] == "-t")
                {
                    if (t + 1 < args.Length)
                    {
                        outtype = args[t + 1];
                    }
                }

                if (args[t] == "-o")
                {
                    if (t + 1 < args.Length)
                    {
                        outfile = args[t + 1];
                    }
                }
            }


            Console.WriteLine("Input sql file: " + inputfile);
            Console.WriteLine("db engine used: " + dbvendor);
            Console.WriteLine("output type: " + outtype);
            Console.WriteLine("output file: " + outfile);

            string lcsqltext = "";

            //Reading from file
            try
            {
                StreamReader re = File.OpenText(inputfile); //new StreamReader(inputfile,new UnicodeEncoding());//
                // Console.WriteLine("The encoding used was {0}.", re.CurrentEncoding);

                string input = null;
                while ((input = re.ReadLine()) != null)
                {
                    lcsqltext = lcsqltext + input + Environment.NewLine;
                    // Console.WriteLine(input);
                }
            }
            catch (Exception e)
            {
                // Let the user know what went wrong.
                Console.WriteLine("The file could not be read:");
                Console.WriteLine(e.Message);
            }


            //Create instance of sql parser according to database vendor you selected
            TDbVendor dbv;
            if (dbvendor == "access")
            {
                dbv = TDbVendor.DbVAccess;
            }
            else if (dbvendor == "db2")
            {
                dbv = TDbVendor.DbVDB2;
            }
            else if (dbvendor == "mssql")
            {
                dbv = TDbVendor.DbVMssql;
            }
            else if (dbvendor == "mysql")
            {
                dbv = TDbVendor.DbVMysql;
            }
            else if (dbvendor == "oracle")
            {
                dbv = TDbVendor.DbVOracle;
            }
            else
            {
                dbv = TDbVendor.DbVMssql;
            }

            TGSqlParser sqlparser = new TGSqlParser(dbv);
            Console.WriteLine(lzbasetype.DbVendorStr[(int)dbv]);


            //set the input sql text	
            sqlparser.SqlText.Text = lcsqltext;

            int i = sqlparser.Parse();
            if (i != 0){
                Console.WriteLine("syntax error: "+sqlparser.ErrorMessages);
                return ;
            }

            string outputstr = "";

            lzbasetype.gFmtOpt.HighlightingFontsize = 10;
            

            //setup color of output, color setted here must be prefixed by #, and is in RGB format.
            // you can set Foreground directly if you know exactly what's color the number stands for.

            // identifier
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkIdentifer].SetForegroundInRGB("#800000");

            // keyword
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkStandardkeyword].SetForegroundInRGB("#0000FF");

            // number
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkNumber].SetForegroundInRGB("#000000");

            // function
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkFunction].SetForegroundInRGB("#FF0080");

            // symbol such as +,-, (
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkSymbol].SetForegroundInRGB("#C0C0C0");

            // bind variable in oracle
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkParameter].SetForegroundInRGB("#800000");

            // single quote string
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkSQString].SetForegroundInRGB("#FF0000");

            // double quote string
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkDQString].SetForegroundInRGB("#FF0000");

            // datatype
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkDatatype].SetForegroundInRGB("#000000");

            // comment, double hyphen
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkComment_dh].SetForegroundInRGB("#008000");
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkComment_dh].StyleItalic = true;
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkComment_dh].StyleBold = false;
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkComment_dh].StyleStrikeout = false;
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkComment_dh].StyleUnderline = false;

            // comment, slash star
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkComment_ss].SetForegroundInRGB("#008000");

            // oracle exception
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkOracleexception].SetForegroundInRGB("#800000");

            // oracle sqlplus
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkOraclesqlplus].SetForegroundInRGB("#800000");

            // sql server system variable
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfkMssqlsystemvar].SetForegroundInRGB("$0000FF");

            // sql variable
            lzbasetype.gFmtOpt.HighlightingElements[(int)TLzHighlightingElement.sfksqlvar].SetForegroundInRGB("#00000F");


            Console.WriteLine("Working...");
            // Console.WriteLine(lcsqltext);
          

            switch (outtype)
            {
                case "rtf":
                    outputstr = sqlparser.ToRTF(TOutputFmt.ofrtf);
                    break;
                case "html":
                    outputstr = sqlparser.ToHtml(TOutputFmt.ofhtml);
                    break;
                case "html2":
                    outputstr = sqlparser.ToHtml(TOutputFmt.ofhtml2);
                    break;
                default:
                    outputstr = sqlparser.ToHtml(TOutputFmt.ofhtml);
                    break;
            }


            if (outfile.Length > 0)
            {
                //save to file
                StreamWriter w = File.CreateText(outfile);
                w.Write(outputstr);
                w.Flush();
                w.Close();
                Console.WriteLine(outfile + " was created");

            }
            else
            {
                Console.WriteLine(outputstr);
            }

        }        
    }
}
